package com.ruoyi.common.datapermission.auth;

import com.alibaba.fastjson.JSONObject;
import com.mybatisflex.core.dialect.OperateType;
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.QueryTable;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.table.TableInfo;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.datapermission.rule.DataPermissionRule;
import com.ruoyi.common.datapermission.rule.DataPermissionRuleFactory;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.mybatisflex.core.constant.SqlConsts.AND;
import static com.mybatisflex.core.constant.SqlConsts.EQUALS;
import static com.ruoyi.system.domain.table.SysDeptTableDef.SYS_DEPT;

/**
 * 权限处理
 */
@Slf4j
public class AuthDialectImpl extends CommonsDialectImpl {

    private DataPermissionRuleFactory dataPermissionRuleFactory;

    public AuthDialectImpl() {
        this.dataPermissionRuleFactory = SpringUtils.getBean(DataPermissionRuleFactory.class);
    }

    @Override
    public void prepareAuth(QueryWrapper queryWrapper, OperateType operateType) {
        List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
        if (queryTables == null || queryTables.isEmpty()) {
            return;
        }
        log.info("prepareAuth,queryTables：{}", JSONObject.toJSONString(queryTables.stream().map(QueryTable::getName).collect(Collectors.toSet())));
        List<DataPermissionRule> dataPermissionRule = dataPermissionRuleFactory.getDataPermissionRule();
        Optional.ofNullable(dataPermissionRule).ifPresent(rules -> rules.forEach(rule -> rule.dealDataPermissionSQL(queryWrapper, queryTables)));
//        for (QueryTable queryTable : queryTables) {
////            if (PROJECT.getName().equals(queryTable.getName())) {
////                queryWrapper.and(PROJECT.INSERT_USER_ID.eq(1));
////            }
//            if (SYS_DEPT.getName().equals(queryTable.getName())) {
//                queryWrapper.and(SYS_DEPT.DEPT_ID.eq(1));
//            }
//        }
        super.prepareAuth(queryWrapper, operateType);
    }

    @Override
    public void prepareAuth(String schema, String tableName, StringBuilder sql, OperateType operateType) {
//        if (PROJECT.getName().equals(tableName)) {
//            sql.append(AND).append(wrap("insert_user_id")).append(EQUALS).append(1);
//        }
//        if (SYS_DEPT.getName().equals(tableName)) {
//            sql.append(AND).append(wrap("dept_id")).append(EQUALS).append(1);
//        }
        List<DataPermissionRule> dataPermissionRule = dataPermissionRuleFactory.getDataPermissionRule();
        Optional.ofNullable(dataPermissionRule).ifPresent(rules -> rules.forEach(rule -> rule.dealDataPermissionSQL(schema, tableName, sql)));
        super.prepareAuth(schema, tableName, sql, operateType);
    }

    @Override
    public void prepareAuth(TableInfo tableInfo, StringBuilder sql, OperateType operateType) {
//        if (PROJECT.getName().equals(tableInfo.getTableName())) {
//            sql.append(AND).append(wrap("insert_user_id")).append(EQUALS).append(1);
//        }
//        if (SYS_DEPT.getName().equals(tableInfo.getTableName())) {
//            sql.append(AND).append(wrap("dept_id")).append(EQUALS).append(1);
//        }
        List<DataPermissionRule> dataPermissionRule = dataPermissionRuleFactory.getDataPermissionRule();
        Optional.ofNullable(dataPermissionRule).ifPresent(rules -> rules.forEach(rule -> rule.dealDataPermissionSQL(tableInfo, sql)));
        super.prepareAuth(tableInfo, sql, operateType);
    }
}
